package fimuni.pb138.repositar;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;

/**
 * Handles requests for the application home page.
 */
@Controller
public class ArtifactController {

	private static final Logger logger = LoggerFactory
			.getLogger(ArtifactController.class);

	@Autowired
	WARService warService;

	@Autowired
	WSDLService wsdlService;

	@Autowired
	XSDService xsdService;

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public ModelAndView showStartupScreen(Model model,
			HttpServletRequest request) {

		ModelAndView mav = new ModelAndView("home", model.asMap());
		return mav;
	}

	@RequestMapping(value = "/download/{file_name}/{original_filename}", method = RequestMethod.GET)
	public void getFile(
			@PathVariable("file_name") String fileName,
			@PathVariable("original_filename") String originalFilename,
			HttpServletResponse response) {
		try {
			// get your file as InputStream
			File f = new File(ArtifactUtils.STORAGE_PATH+fileName);
			
			logger.error(f.getAbsolutePath());
			InputStream is = new FileInputStream(f);
			// copy it to response's OutputStream
			IOUtils.copy(is, response.getOutputStream());
			response.setHeader("Content-Disposition", "attachment; filename="+originalFilename); 
			response.flushBuffer();
	    } catch (IOException ex) {
			logger.error(ex.getLocalizedMessage());
	    }

	}

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public String save(@ModelAttribute("fileObject") FileObject uploadForm,
			Model map, HttpServletRequest request, HttpServletResponse response) {
		try {
			MultipartFile file = uploadForm.getFile();
			String filename = file.getOriginalFilename();

			int index = filename.lastIndexOf('.');
			if (filename.length() < index + 4) {
				logger.error("Unknown file uploaded");
				response.sendRedirect(request.getContextPath() + "?error=2");
				return "home";
			}

			String suffix = filename.substring(index + 1, index + 4);
			switch (suffix.toLowerCase()) {
			case "war":
				warService.processWar(file);
				break;
			case "xsd":
				xsdService.processXSD(file);
				break;
			case "wsd":
				wsdlService.processWSDL(file);
				break;
			default:
				logger.error("Unknown file uploaded");
				response.sendRedirect(request.getContextPath() + "?error=2");
				break;
			}
			response.sendRedirect(request.getContextPath() + "?type="+suffix.toLowerCase());
		} catch (Exception e) {
			logger.error("Upload failed: " + e.getLocalizedMessage());
		}
		
		return "home";
	}

	@RequestMapping(value = "/getAll.html", method = RequestMethod.POST)
	public @ResponseBody
	String getAll(@RequestBody String type) {
		Gson gson = new Gson();
		String result = null;
		if (type.equals("war")) {
			List<WARFile> allWar = warService.getAllWARs();
			result = gson.toJson(allWar);
		} else if (type.equals("wsdl")) {
			List<WSDLFile> allWsdl = wsdlService.getAllWSDLs();
			result = gson.toJson(allWsdl);
		} else {
			List<XSDFile> allXsd = xsdService.getAllXSDs();
			result = gson.toJson(allXsd);
		}
		return result;
	}

	@RequestMapping(value = "/getVersions.html", method = RequestMethod.POST)
	public @ResponseBody
	String getVersions(@RequestBody String data) {
		Gson gson = new Gson();
		VersionObject version = gson.fromJson(data, VersionObject.class);
		String result = null;
		if (version.getType().equals("war")) {
			WARFile war = warService.findWARbyIDandVersion(version.getId(),
					version.getVersion());
			result = gson.toJson(war);
		} else if (version.getType().equals("wsdl")) {
			WSDLFile wsdl = wsdlService.findWSDLbyIDandVersion(version.getId(),
					version.getVersion());
			result = gson.toJson(wsdl);
		} else {
			XSDFile xsd = xsdService.findXSDbyIDandVersion(version.getId(),
					version.getVersion());
			result = gson.toJson(xsd);
		}
		return result;
	}

	@RequestMapping(value = "/search.html", method = RequestMethod.POST)
	public @ResponseBody
	String search(@RequestBody String data) {
		Gson gson = new Gson();
		SearchData sd = null;
		sd = gson.fromJson(data, SearchData.class);
		// System.out.println(sd.getType());
		String result = null;
		if (sd.getType().equals("war")) {
			List<WARFile> foundwar = warService.findWARbyMetadata(sd.getName(),
					sd.getListener(), sd.getFilter());
			result = gson.toJson(foundwar);
		} else if (sd.getType().equals("wsdl")) {
			List<WSDLFile> foundwsdl = wsdlService.findWSDLbyMetadata(
					sd.getName(), sd.getOperation(), sd.getResponse(),
					sd.getRequest());
			result = gson.toJson(foundwsdl);
		} else {
			List<XSDFile> foundxsd = xsdService.findXSDbyMetadata(sd.getName(),
					sd.getSimpleType(), sd.getComplexType(), sd.getAttribute(),
					sd.getElement());
			result = gson.toJson(foundxsd);
		}
		return result;
	}
}
